package edu.gatech.ece6102;

import edu.gatech.ece6102.beans.AddressBean;
import edu.gatech.ece6102.beans.Message;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;

/**
 * User: deepal
 * Date: Sep 28, 2010
 * Time: 6:57:37 PM
 */
public class LogbasedExecutor implements Runnable {
    private Queue<Message> messageQueue;
    private Queue<Message> pmessageQueue;
    private Logger messageLogger;
    private ArrayList<AppServer> appServers;
    int index = 0;
    private HashMap<String, AppServer> appServerMapping;

    public LogbasedExecutor(Queue<Message> messageQueue, Logger messageLogger) {
        this.messageQueue = messageQueue;
        pmessageQueue = new LinkedList<Message>();
        this.messageLogger = messageLogger;
        appServers = new ArrayList<AppServer>();
        appServerMapping = new HashMap<String, AppServer>();
    }

    public void run() {
        while (true) {
            if (!pmessageQueue.isEmpty()) {
                System.out.println("Processing P queue");
                Message message = pmessageQueue.poll();
                if (message != null) {
                    AppServer appServer = getNext();
                    if(appServer == null){
                        continue;
                    }
                    appServer.addMessage(message);
                }
            }
            if (messageQueue.isEmpty()) {
                try {
                    synchronized (this) {
                        this.wait();
                    }
                } catch (InterruptedException e) {
                    continue;
                }
            }
            Message message = messageQueue.poll();
            if (message != null) {
                AppServer appServer = getNext();
                  if(appServer == null){
                        continue;
                    }
                appServer.addMessage(message);
            }
        }
    }

    private AppServer getNext() {
        int size = appServers.size();
        if(size == 0){
            return null;
        }
        int res = index % size;
        index++;
        AppServer appServer = appServers.get(res);
        while (appServer.isReportingError()) {
            return getNext();
        }
        return appServer;
    }

    public void addToQueue(Message message) {
        System.out.println("Added to P queue");
        pmessageQueue.add(message);
        synchronized (this) {
            this.notify();
        }
    }

    public void removeFromQueue(Message message) {
        messageQueue.remove(message);
    }

    public void addAppServer(AddressBean address, String name) {
        if (appServerMapping.get(name) == null) {
            AppServer server = new AppServer(1, address, this, name);
            appServers.add(server);
            appServerMapping.put(name, server);
            System.out.println("Added a new Server: " + server);
        }
    }

    public void removeAppServer(AppServer server) {
        System.out.println("Before " + appServers);
        synchronized (this) {
            appServers.remove(server);
        }
        System.out.println("After " + appServers);
    }

    public void removeAppServer(String name) {
        AppServer server = appServerMapping.get(name);
        removeAppServer(server);
        appServerMapping.remove(name);
    }

   

}
